package com.wt.demo.threadtest.concurrentsort;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @description
 * @author: wangtao
 * @date:9:33 2018/6/12
 * @email:tao8.wang@changhong.com
 */
public class ConcurrentSort {

    static int[] arr = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};

    public static void main(String[] args) throws InterruptedException {
//        nonConcurrent();
        conCurrent();
    }

    public static void nonConcurrent() {
        int start = 0;
        boolean exchanged = true;
        while (exchanged || start == 1) {
            exchanged = false;
            for (int i = start; i < arr.length - 1; i += 2) {
                if (arr[i] > arr[i + 1]) {
                    int temp = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1] = temp;
                    exchanged = true;
                    System.out.println(arr[i] + "<" + arr[i + 1] + " exchanged");
                }
            }
            start = start == 0 ? 1 : 0;
            System.out.println("----------------------------->change start to " + start);
        }
        for (int i : arr) {
            System.out.print(i + ",");
        }
    }

    static boolean changedFlag = true;

    static synchronized void setChangedFlag(boolean b) {
        changedFlag = b;
    }

    static class ExchangeTask implements Runnable {

        int index;
        CountDownLatch latch;

        public ExchangeTask(int index, CountDownLatch latch) {
            this.index = index;
            this.latch = latch;
        }

        @Override
        public void run() {
            if (arr[index] > arr[index + 1]) {
                int temp = arr[index];
                arr[index] = arr[index + 1];
                arr[index + 1] = temp;
                setChangedFlag(true);
                System.out.println(arr[index] + "<" + arr[index + 1] + " exchanged");
            }
            latch.countDown();
        }
    }

    public static void conCurrent() throws InterruptedException {
        int start = 0;
        ExecutorService pool = Executors.newCachedThreadPool();
        while (changedFlag || start == 1) {
            setChangedFlag(false);
            CountDownLatch latch = new CountDownLatch((arr.length - 1 - start) / 2);
            for (int i = start; i < arr.length - 1 - start; i += 2) {
                pool.submit(new ExchangeTask(i, latch));
            }
            start = start == 1 ? 0 : 1;
            latch.await();
        }
        for (int k : arr) {
            System.out.print(k + ",");
        }
    }

}
